<?php
// header("Content-Type:text/html;charset=utf-8");
  trait Date{
    public function practiceDate(){

      // 返回时区数据库的版本。
      $this->pri(timezone_version_get());
      return;

      //返回时区的所有转换。
      $this->pri(timezone_transitions_get(timezone_open('Asia/Shanghai')));
      return;

      //根据时区缩略语返回时区名称。二三参见W3c
      echo timezone_name_from_abbr('EST');
      return;

      //返回指定地区位置信息,参数必须DateTimeZone对象
      $this->pri(timezone_location_get(timezone_open('Asia/Shanghai')));
      return;

      //返回包含所有时区标识符的索引数组。
      $this->pri(timezone_identifiers_list());
      return;

      //输出 "act" 时区的夏令时（dst）、偏移量和时区名称：
      $this->pri(timezone_abbreviations_list());
      return;

      //strptime该函数未在 Windows 平台下实现。

      //返回微秒数【时间戳】,一参为true时返回浮点数
      echo microtime();
      echo '<br/>'.microtime(true);
          //返回值就是微秒数,不用格式化
      // echo '<br/>'.date('u',microtime(1));
      return;

      //索引数组形式返回本地时间,二参为true返回关联数组
      $this->pri(localtime(time()));
      $this->pri(localtime(time(),true));
      return;

      //idate 单个字符format格式化日期
      echo idate('i');
      return;

      //☆gmstrftime()同下 用UTC

      //☆strftime()根据地区设置格式化时间输出字符
      echo(strftime("%B %d %Y, %X %Z",mktime(20,0,0,12,31,98))."<br>");
      setlocale(LC_MONETARY,"zh");
      echo(strftime("%Y. %B %d. %A. %X %Z"));
      return;

      // gmmktime( == date_default_timezone_set('UTC');mktime();

      //gmdate() 函数格式化 【GMT/UTC】 日期和时间，并返回格式化的日期字符串。
      date_default_timezone_set('Asia/Shanghai');
      echo date('Y-m-d H:i:s',strtotime('now'));
      echo '<br/>'.gmdate('Y-m-d H:i:s',strtotime('now'));
      return;

      /**
       * gettimeofday()
       * 默认返回关联数组，带有如下数组键名：
       * [sec] - Unix 纪元以来的秒
       * [usec] - 微秒
       * [minuteswest] - 格林尼治以西的分
       * [dsttime] - 夏令时修正类型
       */
       $this->pri(gettimeofday());
       return;

      // getdate() 函数返回某个时间戳或者当前本地的日期/时间的日期/时间信息。
          //设置时区函数
      date_default_timezone_set('Asia/Shanghai');
      $this->pri(getdate());
      return;

      //※※※date format表http://www.w3school.com.cn/php/func_date_date.asp

      $date = date_create('now',timezone_open('Asia/Shanghai'));
      date_timezone_set($date,timezone_open('UTC'));
      echo timezone_name_get(date_timezone_get($date));
      return;

      echo timezone_name_get(date_timezone_get(date_create()));
      return;

      //设置(修改)DateTime对象中的时间戳
      $date = date_create('21:50',timezone_open('Asia/Shanghai'));
      echo date_format($date,'H:i:s a');
      date_timestamp_set($date,strtotime('now'));
      echo '<br/>'.date_format($date,'H:i:s a');
      return;

      //输出(提取)DateTime对象中的时间戳
      echo date_timestamp_get(date_create());
      return;

      //设置时间,参数依次为 DateTime hour minute secounds
      $date = date_create('2018-10-1 12:59:59',timezone_open('Asia/Shanghai'));
      date_time_set($date,21,47);
      echo date_format($date,'H:i:s a');
      return;

      //日出日落黄昏开始、结束。二三参经纬度必须
      $this->pri(date_sun_info(strtotime('now'),31.2283,121.4755));
      return;

      //日落时间,详尽参数同下
      echo date_sunset(strtotime('now'));
      return;

      //返回指定日期与地点的日出时间,一参为【时间戳】,详尽经纬参数见w3c
      echo date_sunrise(strtotime('now'));
      return;

      //时间对象减法date_sub,
      $date = date_create('2018-10-1',timezone_open('Asia/Shanghai'));
      date_sub($date,date_interval_create_from_date_string('1 year'));
      echo date_format($date,'Y-m-d');
      return;

      //根据字符串返回日期关联数组,格式必须是strtotime能接受的格式
      $this->pri(date_parse('2018-10-1 12:59:59'));
      return;

      //根据【指定格式】返回关联数组,格式必须是date_create_from_format识别格式
      $result = date_parse_from_format('j-m-Y','1-10-2018');
      $this->pri($result);
      return;

      /**
       * 以指定格式创建DateTime对象
       * 一参格式
       * d - 一个月中的第几天，带前导零
       * j - 一个月中的第几天，不带前导零
       * D - 一周中的某天（Mon - Sun）
       * I - 一周中的某天（Monday - Sunday）
       * S - 一个月中的第几天的英语后缀（st, nd, rd, th）
       * F - 月份名称（January - December）
       * M - 月份名称（Jan - Dec）
       * m - 月份（01 - 12）
       * n - 月份（1 - 12）
       * Y - 年份（例如 2013）
       * y - 年份（例如 13）
       * a 和 A - am 或 pm
       * g - 12 小时制，不带前导零
       * h - 12 小时制，带前导零
       * G - 24 小时制，不带前导零
       * H - 24 小时制，带前导零
       * i - 分，带前导零
       * s - 秒，带前导零
       * u - 微秒（多达六个数字）
       * e、O、P 和 T - 时区标识符
       * U - 自 Unix 纪元以来经过的秒数
       * （空格）
       * # - 下列分隔符之一：;、:、/、.、,、-、(、)
       * ? - 一个随机字节
       * - 随机字节直到下一个分隔/数字
       * ! - 重置所有字段到 Unix 纪元
       * | - 如果所有字段都还没被解析，则重置所有字段到 Unix 纪元
       * + - 如果存在，字符串中的尾随数据将导致警告，不是错误

       * 三参timezone时区对象
       */
      $date = date_create_from_format('Y-m-d','2018-10-1',timezone_open('Asia/Shanghai'));
      echo date_format($date,'Y/m/d');
      return;

      //返回DateTime对象与UTC格林威治时间差【单位秒】
      echo date_offset_get(date_create('2018-10-1',timezone_open('Asia/Shanghai')));
      echo '<br/>'.date_offset_get(date_create('2018-10-1',timezone_open('America/New_York')));
      return;

      //修改DateTime对象 内的时间戳
      $date = date_create('2018-10-1',timezone_open('Asia/Shanghai'));
      date_modify($date,'+1 week');
      echo date_format($date,'Y-m-d l H:i:s a');
      return;

      /**
       * 设置日期 date_isodate_set() 函数根据 ISO 8601 标准
       * 使用周和天的【偏移量】（而不是使用一个具体的日期）。
       * 一参 DateTime Object
       * 234参 year 【week】的偏移量 day的偏移量
       */
      echo date_format(date_isodate_set(date_create(),2018,40),'Y-m-d l H:i:s a');
      return;

      /**
       * 格式化输出时间区间对象
       * 同Interval->format即:DateInterval::format()
       * format参数列表
       * % - Literal %
       * Y - 年，至少 2 个数字，带前导零（例如 03）
       * y - 年（例如 3）
       * M - 月，带前导零（例如 06）
       * m - 月（例如 6）
       * D - 日，带前导零（例如 09）
       * d - 日（例如 9）
       * a - 由 date_diff() 得出的两个日期间隔的总天数
       * H - 小时，带前导零（例如 08、23）
       * h - 小时（例如 8、23）
       * I - 分，带前导零（例如 08、23）
       * i - 分（例如 8、23）
       * S - 秒，带前导零（例如 08、23）
       * s - 秒（例如 8、23）
       * R - 当负数时为符号 "-"，当正数时为符号 "+"
       * r - 当负数时为符号 "-"，当正数时为空
       * 注释：每个格式字符串必须以 % 符号作为前缀！
       */
      $diff = date_diff(date_create('2017-10-12'),date_create('2018-10-1'));
      echo date_interval_format($diff,'%R%a day');
      echo '<br/>'.$diff->format('%R%a day');
          //没用明白,应该是上面使用方法
      // echo '<br/>'.DateInterval::format('%R%a day');
      return;

      //返回日期函数产生的错误 date_get_last_errors
      echo $this->create_errors();
      return;

      //计算两个DateTime对象的差值,三参为true则必输出正值,默认false
      //date_diff函数返回的是一个【时间区间对象】
      $diff = date_diff(date_create('2017-10-12'),date_create('2018-10-1'));
      $this->pri($diff);
          //格式化 目测%R是符号 %a是数据(日期)
      echo $diff->format('%R%adays');
          //date_format()格式化不了区间,date_interval_format可以
      return;

      //给DateTime对象设置新日期,234参顺序year month day
      $date = date_create(NULL,timezone_open('Asia/Shanghai'));
      echo date_format($date,'Y-m-d l H:i:s a');
      date_date_set($date,2018,10,1);
      echo '<br/>',date_format($date,'Y-m-d l H:i:s a');
      return;

      /**
       * 设置DateInterval对象[日期区间]
       * http://php.net/manual/en/dateinterval.createfromdatestring.php
       * DateInterval::createFromDateString();参数为时间区间英文描述
       * 上述函数别名date_interval_create_from_date_string()
       * 直接使用DateInterval的构造
       * 构造参数分析(简写)
       * P-之后xx时间,D-day,W-weeks,M-months,Y-years,H-hours,S-seconds
       * 连写(T?不知什么格式?),详见上述※URL※
       */

      $i = new DateInterval('P100D');
      $this->pri($i);
      $i = DateInterval::createFromDateString('100 days');
      $this->pri($i);
      $this->pri(date_interval_create_from_date_string("100 days"));
      return;

      //格式化【必须】由date_create创建的DateTime对象
      $this->pri($dataTime = date_create('2018-10-1 10:59:59'));
      echo date_format($dataTime,'Y/m/d l H:i:s a');
          //※※※DateTime对象->format方法达到同样的功能※※※
      echo '<br/>'.$dataTime->format('Y/m/d l H:i:s a');
      return;

      //返回时区名称(参数为DateTimeZone对象)
      echo timezone_name_get(timezone_open('Asia/Shanghai'));
      return;

      //创建DateTimeZone对象[时区表见w3c]
      $this->pri(timezone_open('Asia/Shanghai'));
      return;

      /**
       * 创建新的DateTime对象【Object】
       * 一参为NULL == NOW
       * 一参格式 year-month-day hour:minute:second
       * 二参为【时区※对象※】 默认当前时区
       */
      // date_default_timezone_set('Asia/Shanghai');
      echo date_default_timezone_get();
      $this->pri(date_create());
      $this->pri(date_create('2018-10-1 10:59:59'));
      $this->pri(date_create(NULL,timezone_open('Asia/Shanghai')));
      return;

      /**
       * checkdate()
       * 检测日期是否为格里高利(标准)日期
       * 参数顺序※※※※month day year※※※※
       */
      var_dump(checkdate(10,31,2017));
      var_dump(checkdate(10,32,2017));
      return;

      /**
       * strtotime二参
       * 在二参基础上计算一参面试的时间,二参默认为now
       * 时间戳比较大小
       */

      echo $now = $i = strtotime('now');
      echo '<br/>'.$nextWeek = strtotime('1 week');
      while ($i < $nextWeek) {
        echo '<br/>'.date('m-d',$i = strtotime('+1 day',$i));
      }
      return;

      /**
       * ※※※strtotime※※※
       * 一参用任何英文文本描述的时间
       * 注意格林威治时间：0-69 会映射为 2000-2069，值 70-100 会映射为 1970-2000。
       * ※※strtotime 不安全 注意检测字符串※※
       */

      date_default_timezone_set('Asia/Shanghai');
      echo date('Y-m-d l H:i:s a',strtotime('tomorrow'));
      echo '<br/>'.date('Y-m-d l H:i:s a',strtotime('"tomorrow"'));
      echo '<br/>'.date('Y-m-d l H:i:s a',strtotime($this->test_str('"tomorrow"')));
      return;

      date_default_timezone_set('Asia/Shanghai');
      echo date('Y-m-d l H:i:s a',strtotime("now"));
      echo '<br/>'.date('Y-m-d l H:i:s a',strtotime("tomorrow"));
      echo '<br/>'.date('Y-m-d l H:i:s a',strtotime("1 day"));
      echo '<br/>'.date('Y-m-d l H:i:s a',strtotime("2 day"));
      echo '<br/>'.date('Y-m-d l H:i:s a',strtotime("-1 day"));
          //可以看到next 并不准确 用1代替next -1代替last
      echo '<br/>'.date('Y-m-d l H:i:s a',strtotime("next week"));
      echo '<br/>'.date('Y-m-d l H:i:s a',strtotime("1 week"));

      echo '<br/>'.date('Y-m-d l H:i:s a',strtotime("3 January 99"));
      echo "<br/>一周零两天四小时两秒后:",date("Y-m-d G:H:s",strtotime("+1 week 2 days 4 hours 2 seconds"));
      return;

      //mktime创建时间戳,不是用参数则创建当前本地时间戳【已废Deprecated】
      date_default_timezone_set('Asia/Shanghai');
      echo date('Y-m-d l H:i:s a',mktime());
      echo '<br/>'.date('Y-m-d l H:i:s a',mktime(9, 12, 31, 7, 11, 2018));
      //nextweek【time加法算的】函数
      echo '<br/>nextweek：'.date('Y-m-d l H:i:s a',time()+(7*24*60*60));
      return;

      /**
       * 在国际无线电通信领域，使用一个统一的时间，该时间称为通用协调时间（UTC）
       * UTC与格林威治标准时间（GMT）相同。
       * date不加二参就是用本地时间,加了为时间戳
       * time返回当前时间戳
       */
      //格式化日期 | 时间
      echo date('Y-m-d',time());
      echo '<br/>'.date('H:i:s',time());
      echo '<br/>'.date('Y-m-d H:i:s',time());
          //特殊 L(小写),当前星期几
      echo '<br/>'.date("l");
          //输出当前时区(默认)
      echo '<br/>'.date_default_timezone_get();   //输出UTC
          //a 午前午后
      echo '<br/>'.date('H:i:s a',time());

      date_default_timezone_set("Asia/Shanghai");
      echo '<br/>'.date('H:i:s a',time());

      echo '<br/>版权所有 2008-'.date("Y");

      echo '<br/>'.date('H:i:s');
      echo '<br/>'.date('Y-m-d H:i:s');
      return;
    }

    public function test_str($str){
      $str = trim($str);  //去两侧预定义字符
      $str = stripslashes($str); //去两侧反斜杠
      $str = htmlspecialchars($str,ENT_QUOTES); //去除单引号和双引号
      return $str;
    }

    public function create_errors(){
      date_create("aecubdjpoi%&&/");
      // $this->pri(date_get_last_errors());
      $result = date_get_last_errors();
      $wrong = '';
      $wrong .= 'Line'.$result['error_count'];
      $wrong .= '：error'.$result['warning_count'];
      rsort($result['errors']);
      $wrong .= '：'.$result['errors']['0'].'：'.$result['errors'][count($result['errors'])-1];

      foreach ($result['warnings'] as $v) {
        $wrong .= '：'.$v;
      }
      return $wrong;
    }
  }
 ?>
